#pragma once

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "division_engine_core/input.h"
#include "division_engine_core/types/keycode.h"

#include <GLFW/glfw3.h>

#define __DIVISION_GLFW_MAP_KEYCODE__(keycode)                                           \
    [DIVISION_KEYCODE_##keycode] = GLFW_KEY_##keycode

#define __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(keycode)                                     \
    [DIVISION_KEYCODE_NUMPAD_##keycode] = GLFW_KEY_KP_##keycode

const int DIVISION_GLFW_KEYCODE_MAP[] = {
    __DIVISION_GLFW_MAP_KEYCODE__(Q),
    __DIVISION_GLFW_MAP_KEYCODE__(W),
    __DIVISION_GLFW_MAP_KEYCODE__(E),
    __DIVISION_GLFW_MAP_KEYCODE__(R),
    __DIVISION_GLFW_MAP_KEYCODE__(T),
    __DIVISION_GLFW_MAP_KEYCODE__(Y),
    __DIVISION_GLFW_MAP_KEYCODE__(U),
    __DIVISION_GLFW_MAP_KEYCODE__(I),
    __DIVISION_GLFW_MAP_KEYCODE__(O),
    __DIVISION_GLFW_MAP_KEYCODE__(P),
    __DIVISION_GLFW_MAP_KEYCODE__(A),
    __DIVISION_GLFW_MAP_KEYCODE__(S),
    __DIVISION_GLFW_MAP_KEYCODE__(D),
    __DIVISION_GLFW_MAP_KEYCODE__(F),
    __DIVISION_GLFW_MAP_KEYCODE__(G),
    __DIVISION_GLFW_MAP_KEYCODE__(H),
    __DIVISION_GLFW_MAP_KEYCODE__(J),
    __DIVISION_GLFW_MAP_KEYCODE__(K),
    __DIVISION_GLFW_MAP_KEYCODE__(L),
    __DIVISION_GLFW_MAP_KEYCODE__(Z),
    __DIVISION_GLFW_MAP_KEYCODE__(X),
    __DIVISION_GLFW_MAP_KEYCODE__(C),
    __DIVISION_GLFW_MAP_KEYCODE__(V),
    __DIVISION_GLFW_MAP_KEYCODE__(B),
    __DIVISION_GLFW_MAP_KEYCODE__(N),
    __DIVISION_GLFW_MAP_KEYCODE__(M),
    __DIVISION_GLFW_MAP_KEYCODE__(1),
    __DIVISION_GLFW_MAP_KEYCODE__(2),
    __DIVISION_GLFW_MAP_KEYCODE__(3),
    __DIVISION_GLFW_MAP_KEYCODE__(4),
    __DIVISION_GLFW_MAP_KEYCODE__(5),
    __DIVISION_GLFW_MAP_KEYCODE__(6),
    __DIVISION_GLFW_MAP_KEYCODE__(7),
    __DIVISION_GLFW_MAP_KEYCODE__(8),
    __DIVISION_GLFW_MAP_KEYCODE__(9),
    __DIVISION_GLFW_MAP_KEYCODE__(0),

    [DIVISION_KEYCODE_TILDE] = GLFW_KEY_GRAVE_ACCENT,
    [DIVISION_KEYCODE_MINUS] = GLFW_KEY_MINUS,
    [DIVISION_KEYCODE_EQUAL] = GLFW_KEY_EQUAL,
    [DIVISION_KEYCODE_LSQUARE_BRACKET] = GLFW_KEY_LEFT_BRACKET,
    [DIVISION_KEYCODE_RSQUARE_BRACKET] = GLFW_KEY_RIGHT_BRACKET,
    [DIVISION_KEYCODE_BACKSLASH] = GLFW_KEY_BACKSLASH,
    [DIVISION_KEYCODE_SEMICOLON] = GLFW_KEY_SEMICOLON,
    [DIVISION_KEYCODE_QUOTE] = GLFW_KEY_APOSTROPHE,
    [DIVISION_KEYCODE_COMMA] = GLFW_KEY_COMMA,
    [DIVISION_KEYCODE_DOT] = GLFW_KEY_PERIOD,
    [DIVISION_KEYCODE_SLASH] = GLFW_KEY_SLASH,

    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(0),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(1),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(2),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(3),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(4),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(5),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(6),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(7),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(8),
    __DVISION_GLFW_MAP_KEYCODE_NUMPAD__(9),

    [DIVISION_KEYCODE_NUMPAD_ADD] = GLFW_KEY_KP_ADD,
    [DIVISION_KEYCODE_NUMPAD_SUB] = GLFW_KEY_KP_SUBTRACT,
    [DIVISION_KEYCODE_NUMPAD_MUL] = GLFW_KEY_KP_MULTIPLY,
    [DIVISION_KEYCODE_NUMPAD_DIV] = GLFW_KEY_KP_DIVIDE,
    [DIVISION_KEYCODE_NUMPAD_ENTER] = GLFW_KEY_KP_ENTER,
    [DIVISION_KEYCODE_NUMPAD_DOT] = GLFW_KEY_KP_DECIMAL,
    [DIVISION_KEYCODE_NUMPAD_EQUAL] = GLFW_KEY_KP_EQUAL,
    [DIVISION_KEYCODE_NUMPAD_NUM_LOCK] = GLFW_KEY_NUM_LOCK,

    [DIVISION_KEYCODE_LEFT_ARROW] = GLFW_KEY_LEFT,
    [DIVISION_KEYCODE_RIGHT_ARROW] = GLFW_KEY_RIGHT,
    [DIVISION_KEYCODE_UP_ARROW] = GLFW_KEY_UP,
    [DIVISION_KEYCODE_DOWN_ARROW] = GLFW_KEY_DOWN,
    [DIVISION_KEYCODE_LCTRL] = GLFW_KEY_LEFT_CONTROL,
    [DIVISION_KEYCODE_RCTRL] = GLFW_KEY_RIGHT_CONTROL,
    [DIVISION_KEYCODE_LWIN] = GLFW_KEY_LEFT_SUPER,
    [DIVISION_KEYCODE_RWIN] = GLFW_KEY_RIGHT_SUPER,
    [DIVISION_KEYCODE_LALT] = GLFW_KEY_LEFT_ALT,
    [DIVISION_KEYCODE_RALT] = GLFW_KEY_RIGHT_ALT,
    [DIVISION_KEYCODE_LSHIFT] = GLFW_KEY_LEFT_SHIFT,
    [DIVISION_KEYCODE_RSHIFT] = GLFW_KEY_RIGHT_SHIFT,
    [DIVISION_KEYCODE_CAPS_LOCK] = GLFW_KEY_CAPS_LOCK,
    [DIVISION_KEYCODE_TAB] = GLFW_KEY_TAB,
    [DIVISION_KEYCODE_ENTER] = GLFW_KEY_ENTER,
    [DIVISION_KEYCODE_ESC] = GLFW_KEY_ESCAPE,
    [DIVISION_KEYCODE_SPACE] = GLFW_KEY_SPACE,

    [DIVISION_KEYCODE_HOME] = GLFW_KEY_HOME,
    [DIVISION_KEYCODE_END] = GLFW_KEY_END,
    [DIVISION_KEYCODE_PAGE_UP] = GLFW_KEY_PAGE_UP,
    [DIVISION_KEYCODE_PAGE_DOWN] = GLFW_KEY_PAGE_DOWN,
    [DIVISION_KEYCODE_BACKSPACE] = GLFW_KEY_BACKSPACE,
    [DIVISION_KEYCODE_DELETE] = GLFW_KEY_DELETE,
    [DIVISION_KEYCODE_INSERT] = GLFW_KEY_INSERT,
    [DIVISION_KEYCODE_PRINT] = GLFW_KEY_PRINT_SCREEN,
    [DIVISION_KEYCODE_PAUSE] = GLFW_KEY_PAUSE,

    __DIVISION_GLFW_MAP_KEYCODE__(F1),
    __DIVISION_GLFW_MAP_KEYCODE__(F2),
    __DIVISION_GLFW_MAP_KEYCODE__(F3),
    __DIVISION_GLFW_MAP_KEYCODE__(F4),
    __DIVISION_GLFW_MAP_KEYCODE__(F5),
    __DIVISION_GLFW_MAP_KEYCODE__(F6),
    __DIVISION_GLFW_MAP_KEYCODE__(F7),
    __DIVISION_GLFW_MAP_KEYCODE__(F8),
    __DIVISION_GLFW_MAP_KEYCODE__(F9),
    __DIVISION_GLFW_MAP_KEYCODE__(F10),
    __DIVISION_GLFW_MAP_KEYCODE__(F11),
    __DIVISION_GLFW_MAP_KEYCODE__(F12),
    __DIVISION_GLFW_MAP_KEYCODE__(F13),
    __DIVISION_GLFW_MAP_KEYCODE__(F14),
    __DIVISION_GLFW_MAP_KEYCODE__(F15),
    __DIVISION_GLFW_MAP_KEYCODE__(F16),
    __DIVISION_GLFW_MAP_KEYCODE__(F17),
    __DIVISION_GLFW_MAP_KEYCODE__(F18),
    __DIVISION_GLFW_MAP_KEYCODE__(F19),
};